package foxesandrabbits.species;

import java.util.Iterator;
import java.util.List;

import foxesandrabbits.field.*;
/**
 * The model of a Bat.
 * vampire bats which survive on the blood of other actors (except snails)
 * An actor bitten by a vampire bat turns into a vampire bat
 * If a vampire bat doesn't get enough blood, it turns back into the original actor.
 * 
 * @author Luttiau Hadrien
 *
 */
public class Bat extends Killer{

	private AliveObject previousLife;
	private static int BAT_BLOOD_VALUE=4;
	private static double BAT_BREEDING_PROBABILITY=0;

	public Bat(Field field, Location location,AliveObject previousLife) {
		super(false, field, location, BAT_BLOOD_VALUE,BAT_BREEDING_PROBABILITY);
		this.previousLife=previousLife;
		this.preys = new Class[] { Rabbit.class, Fox.class, Hunter.class, Wolf.class };
	}

	public Location findBlood(List<AliveObject> newBat)
	{
		Field field = getField();
		List<Location> adjacent = field.adjacentLocations(getLocation());
		Iterator<Location> it = adjacent.iterator();
		while(it.hasNext()) {
			Location where = it.next();
			Object animal = field.getObjectAt(where);

			for (Class<?> classPrey : this.preys)
			{
				if(animal != null && animal.getClass().equals(classPrey)) {
					AliveObject prey = (AliveObject) animal;
					
					// 6.6% chances to bite successfully the prey
					if(prey.isAlive() && rand.nextInt(15) == 1) 
					{ 
						Bat nBat=new Bat(prey.getField(), prey.getLocation(), prey);
						prey.setDead();
						newBat.add(nBat);
						foodLevel = BAT_BLOOD_VALUE;
						//System.out.println("A " + prey.getClass().getName() + " has been bitten by a bat !!!!");
						return where;
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * Indicate that the animal is no longer alive.
	 * It is removed from the field.
	 */
	protected void setDead(List<AliveObject> newAnimals)
	{
		
		if(previousLife==null)
			return;
		
		this.previousLife.setAlive();
		this.previousLife.setField(this.getField());
		this.previousLife.setLocation(this.getLocation());
		
		super.setDead();
		
		newAnimals.add(this.previousLife);
		
	}


    protected void incrementHunger(List<AliveObject> newAnimals)
    {
        foodLevel--;
        if(foodLevel <= 0) {
            this.setDead(newAnimals);
        }
    }
	
	/**
	 * This is what the fox does most of the time: it hunts for
	 * rabbits. In the process, it might breed, die of hunger,
	 * or die of old age.
	 * @param newAnimals A list to return newly born animals.
	 */
	public void act(List<AliveObject> newAnimals)
	{
		this.incrementHunger(newAnimals);
		
		if(isAlive()) 
		{
			Location newLocation = findBlood(newAnimals);
			if(newLocation == null) 
			{ 
				// No food found - try to move to a free location.
				newLocation = getField().freeAdjacentLocation(getLocation());
				
				// Move the bat only if it does not bit
				if (newLocation != null) 
					setLocation(newLocation);
			}
			// Kill the bat if it is stuck
			if(newLocation == null)
			{
				setDead(newAnimals);
				//System.out.println("Bat stuck");
			}
		}
	}

}
